home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1993, 1994 Marc Parmet.
- * This file is part of the Macintosh port of GNU Emacs.
- *
- * GNU Emacs is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
- #if defined(THINK_C)
- #include <MacHeaders>
- #else
- #include <Types.h>
- #include <Memory.h>
- #include <Quickdraw.h>
- #include <Windows.h>
- #include <Errors.h>
- #endif
-
- #include <Aliases.h>
- #include "sys/stat.h"
-
- int
- number_of_volumes(void)
- {
- short err;
- int index;
- HParamBlockRec pb;
-
- index = 1;
- while (1) {
- pb.volumeParam.ioNamePtr = 0L;
- pb.volumeParam.ioVolIndex = index;
- err = PBHGetVInfo(&pb,0);
- if (err) return index-1;
- ++index;
- }
- }
-
- int
- stat_spec_internal(FSSpec *spec,struct stat *st,int stop_at_alias)
- {
- short err;
- CInfoPBRec pb;
- Boolean isFolder,wasAliased;
-
- st->st_nlink = 1;
- st->st_ino = 1; // Zero might flag an error somewhere.
- st->st_atime = st->st_ctime = 0;
- st->st_rdev = 0;
-
- pb.dirInfo.ioFDirIndex = 0;
- pb.dirInfo.ioNamePtr = spec->name;
- pb.dirInfo.ioVRefNum = spec->vRefNum;
- pb.dirInfo.ioDrDirID = spec->parID;
- err = PBGetCatInfo(&pb,0);
- if (err) { set_errno(err); return -1; }
-
- if (pb.dirInfo.ioFlAttrib & 0x10) {
- // Looking at a directory or volume.
- st->st_mode = S_IFDIR | 0777;
- st->st_mtime = pb.dirInfo.ioDrMdDat;
- st->st_size = pb.dirInfo.ioDrNmFls;
- st->st_uid = st->st_gid = (pb.dirInfo.ioDrDirID == fsRtDirID) ? 'vol ' : 'fldr';
- }
- else {
- // Looking at either a plain file or an alias.
- if (stop_at_alias) {
- err = ResolveAliasFile(spec,0,&isFolder,&wasAliased);
- if (err == fnfErr && wasAliased)
- // We allow this case for when the target of an alias cannot be found.
- ;
- else
- if (err) { set_errno(err); return -1; };
- }
- else
- wasAliased = 0;
-
- if (wasAliased)
- st->st_mode = S_IFLNK | 0777;
- else
- st->st_mode = S_IFREG |
- (pb.hFileInfo.ioFlFndrInfo.fdType == 'APPL' ? 0777 : 0666);
-
- // No write permission if file is locked
- if (pb.hFileInfo.ioFlAttrib & 1) st->st_mode &= ~0222;
-
- st->st_mtime = pb.hFileInfo.ioFlMdDat;
- st->st_size = pb.hFileInfo.ioFlLgLen;
- st->st_uid = pb.hFileInfo.ioFlFndrInfo.fdType;
- st->st_gid = pb.hFileInfo.ioFlFndrInfo.fdCreator;
- }
-
- return 0;
- }
-
- int
- stat_internal(char *filename,struct stat *st,int stop_at_alias)
- {
- short err;
- FSSpec spec;
- CInfoPBRec pb;
- Boolean isFolder,wasAliased;
-
- st->st_nlink = 1;
- st->st_ino = 1; // Zero might flag an error somewhere.
- st->st_atime = st->st_ctime = 0;
- st->st_rdev = 0;
-
- err = unixfn2FSSpec_internal(filename,&spec,stop_at_alias);
-
- if (err == nsDrvErr) {
- // Looking at the desktop directory. We pretend there is such a directory.
- st->st_mode = S_IFDIR | 0777;
- st->st_mtime = 0;
- st->st_size = number_of_volumes();
- st->st_uid = st->st_gid = 'desk';
- return 0;
- }
-
- if (err) { set_errno(err); return -1; }
-
- return stat_spec_internal(&spec,st,stop_at_alias);
- }
-